﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Aeon.Emulator
{
    /// <summary>
    /// Provides access to DOS environment variables as a dictionary.
    /// </summary>
    public sealed class EnvironmentVariables : IDictionary<string, string>
    {
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the EnvironmentVariables class.
        /// </summary>
        internal EnvironmentVariables()
        {
        }
        #endregion

        #region Internal Methods
        /// <summary>
        /// Generates a null-separated block of environment strings.
        /// </summary>
        /// <returns>Null-separated block of environment strings.</returns>
        internal byte[] GetEnvironmentBlock()
        {
            StringBuilder sb = new StringBuilder();
            foreach(var pair in variables)
            {
                sb.Append(pair.Key);
                sb.Append('=');
                sb.Append(pair.Value);
                sb.Append('\0');
            }
            sb.Append('\0');

            return Encoding.ASCII.GetBytes(sb.ToString());
        }
        #endregion

        #region Private Fields
        private readonly Dictionary<string, string> variables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        #endregion

        #region IDictionary<string,string> Members
        public void Add(string key, string value)
        {
            this.variables.Add(key, value);
        }
        public bool ContainsKey(string key)
        {
            return this.variables.ContainsKey(key);
        }
        public ICollection<string> Keys
        {
            get
            {
                return this.variables.Keys;
            }
        }
        public bool Remove(string key)
        {
            return this.variables.Remove(key);
        }
        public bool TryGetValue(string key, out string value)
        {
            return this.variables.TryGetValue(key, out value);
        }
        public ICollection<string> Values
        {
            get
            {
                return this.variables.Values;
            }
        }
        public string this[string key]
        {
            get
            {
                return this.variables[key];
            }
            set
            {
                this.variables[key] = value;
            }
        }
        #endregion

        #region ICollection<KeyValuePair<string,string>> Members
        void ICollection<KeyValuePair<string,string>>.Add(KeyValuePair<string, string> item)
        {
            ((ICollection<KeyValuePair<string, string>>)this.variables).Add(item);
        }
        public void Clear()
        {
            this.variables.Clear();
        }
        bool ICollection<KeyValuePair<string, string>>.Contains(KeyValuePair<string, string> item)
        {
            return ((ICollection<KeyValuePair<string, string>>)this.variables).Contains(item);
        }
        void ICollection<KeyValuePair<string, string>>.CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
        {
            ((ICollection<KeyValuePair<string, string>>)this.variables).CopyTo(array, arrayIndex);
        }
        public int Count
        {
            get
            {
                return this.variables.Count;
            }
        }
        bool ICollection<KeyValuePair<string, string>>.IsReadOnly
        {
            get { return false; }
        }
        bool ICollection<KeyValuePair<string, string>>.Remove(KeyValuePair<string, string> item)
        {
            return ((ICollection<KeyValuePair<string, string>>)this.variables).Remove(item);
        }
        #endregion

        #region IEnumerable<KeyValuePair<string,string>> Members
        public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
        {
            return this.variables.GetEnumerator();
        }
        #endregion

        #region IEnumerable Members
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion
    }
}
